package server;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.ServerSocket;
import servlet.MyRequest;
import servlet.MyResponse;
import util.Tools;

public class WebServer {
	
	private static WebServer m_instance = null;
	private ServletServer servletServer;
	private ServerSocket serverSocket;
	private static ServerContext serverContext;
	
	//单例模式获取webServer实例
	synchronized public static WebServer getInstance(){
		if(m_instance==null){
			m_instance = new WebServer();
		}
		return m_instance;
	}
	
	private WebServer(){};
	
	public static ServerContext getServerContext() {
		return serverContext;
	}
	//webServer初始化
	//1.获取ServletServer实例（处理servlet、JSP）
	//2.新建ServerSocket（Socket连接）
	//3.获取ServerContext实例（服务器主要的参数设置）
	private void init(){
		this.servletServer = ServletServer.getInstance();
		try {
			serverSocket = new ServerSocket(5119);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		serverContext = ServerContext.getInstance(this);
	}
	//服务器启动
	public void start(){
		MyConnection newConnection;
		MyRequest request;
		MyResponse response;
		ByteArrayOutputStream outputBuffer;
		HTTPPackage httpPackage;
		this.init();//执行服务器初始化操作
		//死循环监听用户请求	
		while(true){
			newConnection = this.getNewConnection();
			outputBuffer = new ByteArrayOutputStream();
			request = new MyRequest(newConnection.getInputStream());
			response = new MyResponse(outputBuffer);
			request.setResponse(response);
			response.setRequest(request);
			//判断请求资源类型，区分动态和静态请求，静态请求直接由WebServer处理，动态请求交由ServletServer处理
			if(request.getRequestResourceType().equals("static")){
				getStaticResource(request, response);
			}
			else {
				this.servletServer.process(request, response);
			}
			
			//最后，将静态或动态处理器处理的结果同意进行报文的封装，最终返回给客户端
			httpPackage = new HTTPPackage(response);
			//System.out.println(outputBuffer);
			try {
				
				newConnection.getOutputStream().write(httpPackage.getHttpPackage());
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			newConnection.close();
		}
	}
	
	private void getStaticResource(MyRequest request, MyResponse response) {
		String requestResource = request.getRequestResource();
		//拼接请求文件实际物理路径
		String resourceFullPath = WebServer.getServerContext().getServerRootPath()+"/webapps"+requestResource;
		System.out.println(resourceFullPath);
		//读取该文件
		File requestFile = new File(resourceFullPath);
		//如果请求文件存在则将其读取并写入response
		if(requestFile.exists()){
			
			response.setStatus(200);

			try {
				byte[] fileByte = Tools.getBytesFromFile(requestFile);
				response.getOutputBuffer().write(fileByte);
				response.getOutputBuffer().close();
			} catch (FileNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		//如果请求资源不存在，则设置状态为404
		else{
			response.setStatus(404);
			response.setContentType("text/html");
			response.setMessage("404 Not Found");
		}
		
	}

	private MyConnection getNewConnection() {
		MyConnection newConnection = null;
		try {
			newConnection = new MyConnection(this.serverSocket.accept());
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return newConnection;
	}
	//停止服务器，清理相关资源，还没实现
	public void stop(){
		
	}
	
}

